package middleware

import (
	"GinBlog/global"
	"GinBlog/models/response"
	"GinBlog/utils"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

func JWTAuth() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 获取请求方法
		act := c.Request.URL.Path
		act = c.Request.Method + ":" + act
		needLogin := isNeedLogin(act)

		// 我们这里jwt鉴权取头部信息 x-token 登录时回返回token信息 这里前端需要把token存储到cookie或者本地localStorage中 不过需要跟后端协商过期时间 可以约定刷新令牌或者重新登录
		token := c.Request.Header.Get("x-token")
		if token == "" {
			if needLogin {
				global.Logger.Error("未登录",
					zap.String("method", c.Request.Method),
					zap.String("path", c.Request.URL.Path),
					zap.String("query", c.Request.URL.RawQuery),
					zap.String("remote_addr", c.ClientIP()),
				)
				response.NoAuth("未登录", c)
				c.Abort()
				return
			}

		}
		// parseToken 解析token包含的信息
		if token != "" {
			j := utils.NewJWT()
			// parseToken 解析token包含的信息
			claims, err := j.ParseToken(token)
			if err != nil {
				if needLogin {
					global.Logger.Error("未登录或登录已过期",
						zap.String("method", c.Request.Method),
						zap.String("path", c.Request.URL.Path),
						zap.String("query", c.Request.URL.RawQuery),
						zap.String("remote_addr", c.ClientIP()),
					)
					response.NoAuth("未登录或登录已过期", c)
					c.Abort()
					return
				}
			}

			if claims != nil {
				c.Set("UserId", claims.UserID)
				c.Set("Username", claims.Username)
			}
		}
		c.Next()
	}
}

var needJwtMethods = []string{
	"PUT:/blog/comment",
	"DELETE:/blog/comment",
	"POST:/blog/comment",
	"PUT:/blog/post",
	"DELETE:/blog/post",
	"POST:/blog/post",
}

func isNeedLogin(act string) bool {
	needLogin := false
	for njm := range needJwtMethods {
		if act == needJwtMethods[njm] {
			needLogin = true
			break
		}
	}
	return needLogin
}
